package com.spsoft.einvoicetodmz.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.spsoft.core.enums.ResponseEnum;
import com.spsoft.core.model.Result;
import com.spsoft.core.model.leqidmz.param.*;
import com.spsoft.core.model.leqidmz.param.collect.*;
import com.spsoft.core.model.leqidmz.response.*;
import com.spsoft.core.model.leqidmz.response.collect.*;
import com.spsoft.einvoicetodmz.service.DmzApiClientService;
import com.spsoft.einvoicetodmz.service.DmzFeignService;
import com.spsoft.vms.redis.RedisService;
import com.spsoft.vms.redis.constant.RedisConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 调用DMZ接口客户端实现类
 *
 * @author : chenxudong
 * @date : 2024/1/26 10:01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DmzApiClientServiceImpl implements DmzApiClientService {

    public static final String LOG_MSG = "(调用DMZ接口客户端)";

    private final RedisService redisService;

    private final DmzFeignService dmzFeignService;

    @Value(value = "${leqi.dmz.ip}")
    private String ip;

    @Value(value = "${leqi.dmz.macdz}")
    private String macdz;

    @Value(value = "${leqi.dmz.cpuid:}")
    private String cpuid;

    @Value(value = "${leqi.dmz.zbxlh:}")
    private String zbxlh;

    /**
     * 查询纳税人基本信息
     */
    @Override
    public Result<QueryEnterpriseInfoVO> queryEnterpriseInfo(BaseNsrRequestParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询纳税人基本信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryEnterpriseInfoVO> dmzResult = dmzFeignService.queryEnterpriseInfo(params);
        log.info("{}查询纳税人基本信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询纳税人风险信息
     */
    @Override
    public Result<QueryEnterpriseInfoRiskVO> queryEnterpriseRisk(BaseNsrRequestParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询纳税人风险信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryEnterpriseInfoRiskVO> dmzResult = dmzFeignService.queryEnterpriseRisk(params);
        log.info("{}查询纳税人风险信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询税收分类编码信息
     */
    @Override
    public Result<QueryClassifyCodeVO> queryClassifyCode(QueryClassifyCodeParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询税收分类编码信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryClassifyCodeVO> dmzResult = dmzFeignService.queryClassifyCode(params);
        log.info("{}查询税收分类编码信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询可用税率信息
     */
    @Override
    public Result<QueryAvalibleTaxRateVo> queryAvalibleTaxRate(BaseNsrRequestParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询可用税率信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryAvalibleTaxRateVo> dmzResult = dmzFeignService.queryAvalibleTaxRate(params);
        log.info("{}查询可用税率信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询授信额度信息
     */
    @Override
    public Result<QueryCreditlimitVO> queryCreditLimit(BaseNsrRequestParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询授信额度信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryCreditlimitVO> dmzResult = dmzFeignService.queryCreditLimit(params);
        log.info("{}查询授信额度信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 调整授信额度有效期
     */
    @Override
    public Result<QueryCreditPeriodVO> queryCreditPeriod(QueryCreditPeriodParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}调整授信额度有效期入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryCreditPeriodVO> dmzResult = dmzFeignService.queryCreditPeriod(params);
        log.info("{}调整授信额度有效期出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 下载/退回授信额度
     */
    @Override
    public Result<ApplyCreditVO> applyCredit(ApplyCreditParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}下载/退回授信额度入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<ApplyCreditVO> dmzResult = dmzFeignService.applyCredit(params);
        log.info("{}下载/退回授信额度出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 获取数电票批量预赋码信息
     */
    @Override
    public Result<AssignedCodeResponseVO> assignedCode(AssignedCodeParams params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}获取数电票批量预赋码信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<AssignedCodeResponseVO> dmzResult = dmzFeignService.assignedCode(params);
        log.info("{}获取数电票批量预赋码信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 数电票上传
     */
    @Override
    public Result<UploadInvoiceVO> uploadInvoice(List<UploadInvoiceParams> params, String tdys) {
        if (CollectionUtil.isEmpty(params) || params.size() > 100) {
            return Result.ValidateError("上传票数不能为空，且最大票量不能超过100");
        }
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params.get(0), tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        // 服务器ip、mac地址、cpuid、主板序列号赋值
        for (UploadInvoiceParams uploadInvoiceParam : params) {
            uploadInvoiceParam.setIp(ip);
            uploadInvoiceParam.setMacdz(macdz);
            uploadInvoiceParam.setCpuid(cpuid);
            uploadInvoiceParam.setZbxlh(zbxlh);
        }
        // 构造数电票上传入参
        UploadInvoiceParamDto uploadDto = new UploadInvoiceParamDto();
        uploadDto.setUploadInvoiceJson(JSONObject.toJSONString(params));
        uploadDto.setSydwptbh(params.get(0).getSydwptbh());
        uploadDto.setTdys(tdys);

        log.info("{}数电票上传入参：{}", LOG_MSG, JSONObject.toJSONString(uploadDto));
        Result<UploadInvoiceVO> dmzResult = dmzFeignService.uploadInvoice(uploadDto);
        log.info("{}数电票上传出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询数电票上传结果
     */
    @Override
    public Result<QueryUploadInvoiceStatusVO> queryUploadInvoiceStatus(QueryUploadInvoiceStatusParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询数电票上传结果入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryUploadInvoiceStatusVO> dmzResult = dmzFeignService.queryUploadInvoiceStatus(params);
        log.info("{}查询数电票上传结果出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 上传发票汇总确认信息
     */
    @Override
    public Result<BaseResponseVO> uploadInvoiceSummary(UploadInvoiceSummaryParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}上传发票汇总确认信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<BaseResponseVO> dmzResult = dmzFeignService.uploadInvoiceSummary(params);
        log.info("{}上传发票汇总确认信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询发票汇总确认信息
     */
    @Override
    public Result<QueryUploadInvoiceSummaryVO> queryUploadInvoiceSummary(QueryUploadInvoiceSummaryParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询发票汇总确认信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryUploadInvoiceSummaryVO> dmzResult = dmzFeignService.queryUploadInvoiceSummary(params);
        log.info("{}查询发票汇总确认信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 数电红字确认单申请
     */
    @Override
    public Result<ApplyRedConfirmVO> applyRedConfirm(ApplyRedConfirmDetailParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}数电红字确认单申请入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<ApplyRedConfirmVO> dmzResult = dmzFeignService.applyRedConfirm(params);
        log.info("{}数电红字确认单申请出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 数电红字确认单确认
     */
    @Override
    public Result<ConfirmRedConfirmVO> confirmRedConfirm(ConfirmRedConfirmParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}数电红字确认单确认入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<ConfirmRedConfirmVO> dmzResult = dmzFeignService.confirmRedConfirm(params);
        log.info("{}数电红字确认单确认出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询数电红字确认单明细
     */
    @Override
    public Result<QueryRedConfirmDetailVO> queryRedConfirmDetail(QueryRedConfirmDetailParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询数电红字确认单明细入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryRedConfirmDetailVO> dmzResult = dmzFeignService.queryRedConfirmDetail(params);
        log.info("{}查询数电红字确认单明细出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询数电红字确认单列表
     */
    @Override
    public Result<QueryRedConfirmListVO> queryRedConfirmList(QueryRedConfirmListParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询数电红字确认单列表入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryRedConfirmListVO> dmzResult = dmzFeignService.queryRedConfirmList(params);
        log.info("{}查询数电红字确认单列表出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询差额征税编码
     */
    public Result<QueryDifferentialTaxationVO> queryDifferentialTaxCode(BaseUserInfoParam params, String tdys) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, tdys);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询差额征税编码入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<QueryDifferentialTaxationVO> dmzResult = dmzFeignService.queryDifferentialTaxCode(params);
        log.info("{}查询差额征税编码出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }


    /**
     * 批量发票下载申请
     */
    @Override
    public Result<BatchLoadInvoiceVO> batchLoadInvoice(BatchLoadInvoiceParam params) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, null);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}批量发票下载申请入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<BatchLoadInvoiceVO> dmzResult = dmzFeignService.batchLoadInvoice(params);
        log.info("{}批量发票下载申请出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 批量发票下载申请反馈
     */
    @Override
    public Result<BatchLoadInvoiceFeedbackVO> batchLoadInvoiceFeedback(BatchLoadInvoiceFeedbackParam params) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, null);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}批量发票下载申请反馈入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<BatchLoadInvoiceFeedbackVO> dmzResult = dmzFeignService.batchLoadInvoiceFeedback(params);
        log.info("{}批量发票下载申请反馈出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询增量下载发票信息
     */
    @Override
    public Result<IncLoadInvoiceQueryVO> incLoadInvoiceQuery(IncLoadInvoiceQueryParam params) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, null);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询增量下载发票信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<IncLoadInvoiceQueryVO> dmzResult = dmzFeignService.incLoadInvoiceQuery(params);
        log.info("{}查询增量下载发票信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询发票风险信息
     */
    @Override
    public Result<InvoiceRiskQueryVO> invoiceRiskQuery(InvoiceRiskQueryParam params) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, null);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询发票风险信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<InvoiceRiskQueryVO> dmzResult = dmzFeignService.invoiceRiskQuery(params);
        log.info("{}查询发票风险信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 查询发票用途状态信息
     */
    @Override
    public Result<InvoiceUsedStatusQueryVO> invoiceUsedStatusQuery(InvoiceUsedStatusQueryParam params) {
        // 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
        Result<Object> result = setSydwptbhAndTdys(params, null);
        if (!ResponseEnum.SUCCESS.getCode().equals(result.getCode())) {
            return Result.ERRORT(result.getCode(), result.getMessage());
        }
        log.info("{}查询发票用途状态信息入参：{}", LOG_MSG, JSONObject.toJSONString(params));
        Result<InvoiceUsedStatusQueryVO> dmzResult = dmzFeignService.invoiceUsedStatusQuery(params);
        log.info("{}查询发票用途状态信息出参：{}", LOG_MSG, JSONObject.toJSONString(dmzResult));
        return dmzResult;
    }

    /**
     * 根据机构编码从缓存中获取使用单位平台编号并赋值，业务中透传的特定要素赋值
     */
    public <T extends BaseUserInfoParam> Result<Object> setSydwptbhAndTdys(T params, String tdys) {
        String redisKey = String.format(RedisConstant.REDIS_FULL_BSWJ_CACHE_KEY, params.getDeptCode());
        String redisValue = redisService.getCacheObject(redisKey);
        if (StringUtils.isBlank(redisValue)) {
            log.error("{}未查询到当前机构的使用单位平台编号", LOG_MSG);
            return Result.ERROR(ResponseEnum.SYDWPTBH_NOT_FIND_ERROR);
        }
        String sydwbh = JSONObject.parseObject(redisValue).getString("sydwbh");
        if (StringUtils.isBlank(sydwbh)) {
            log.error("{}未查询到当前机构的使用单位平台编号", LOG_MSG);
            return Result.ERROR(ResponseEnum.SYDWPTBH_NOT_FIND_ERROR);
        }
        params.setSydwptbh(sydwbh);
        params.setTdys(tdys);
        return Result.OK();
    }
}
